import React, { PureComponent } from 'react'
import { SearchBar } from 'antd-mobile'
import { connect } from 'react-redux'
import qs from 'querystring'
import { createToggleHeaderAction } from '@/redux/actions/headerVisible'
import { createSearchKeywordAction } from '@/redux/actions/searchKeyword'
import SearchHot from './hot'
import SearchHistory from './history'
import SearchSuggest from './suggest'
import SearchResult  from './result'
import { searchApi } from '@/api'
import { setStorage, getStorage, removeStorage } from '@/utils/storage'
import css from './index.module.scss'
class Search extends PureComponent {

    constructor(props) {
        super(props)
        const keyword = this.getURLSearch(this.props)   
        this.state = {
            currentStatus: 'init',
            value: keyword || '',            
            defaultKey: null,
            searchTimeout: null,
            hots: [],
            suggests: [],
            historys: getStorage('search_history') || []
        }
        this.props.setKeyword(keyword || '')
    }    

    get isInit() {
        return this.state.currentStatus === 'init'
    }

    get isInput() {
        return this.state.currentStatus === 'input'
    }

    get isResult() {
        return this.state.currentStatus === 'result'
    }

    setStatus = value => {
        const status = ['init', 'input', 'result']
        const matchStatus = status.includes(value) ? value : 'init'
        this.setState({
            currentStatus: matchStatus
        })
    }

    handleChange = value => {
        this.props.setKeyword('')
        this.setStatus('input')
        this.setState({
            value
        }, () => {
            this.handleSuggest()
        })
    }    

    handleSuggest = () => {
        const { value, searchTimeout } = this.state
        if (value.trim() === '') {
            this.setState({
                suggests: []
            })
            return
        }
        clearTimeout(searchTimeout)
        const newTimeout = setTimeout(() => {
            this.getSuggest()
        }, 300)
        this.setState({
            searchTimeout: newTimeout
        })
    }

    handleCancel = () => {
        this.setStatus('init')
        this.props.history.push('/')
    }
    
    handleClear = () => {
        this.triggerSearch('')
    }

    handleSearch = value => {
        const { defaultKey } = this.state
        if (value.trim() !== '') {
            this.triggerSearch(value)
        } else if (defaultKey) {
            const { go_type, url } = defaultKey
            if (go_type === 1) {
                // 直接跳转视频详情页
                const bvid = url.replace(/.*(BV.+)/g, '$1')
                this.props.history.push(`/video/${bvid}`)                
            }
        }
    }

    triggerSearch = value => {
        this.setState({
            suggests: []
        })
        value && this.setHistory(value)
        if (value) {
            this.setStatus('result')
        } else {
            this.setStatus('init')
        }
        this.props.history.push(`/search?keyword=${value}`)        
    }

    handleHistoryClear = () => {
        this.setState({
            historys: []
        })
        removeStorage('search_history')
    }
    setHistory = (value) => {
        const vals = getStorage('search_history')
        const matchIndex = vals.findIndex(val => val.value === value)
        if (matchIndex === -1) {
            const { historys } = this.state
            const item = {
                value,
                isHistory: 1,
                timestamp: new Date().getTime()
            }
            const newHistorys = [item, ...historys]
            this.setState({
                historys: newHistorys
            })
            setStorage('search_history', newHistorys)
        }
    }

    getDefaultKey = async () => {
        try {
            if (this.state.defaultKey) {
                return
            }
            const { data } = await searchApi.getDefault()
            this.setState({
                defaultKey: data
            })
        } catch (error) {
            
        }
    }

    getHotSearch = async () => {
        try {
            if (this.state.hots.length) {
                return
            }
            const { list } = await searchApi.getHotSearch()
            if (Array.isArray(list)) {
                this.setState({
                    hots: list.slice(0, 8)
                })
            }
        } catch (error) {
            
        }
    }


    getSuggest = async () => {
        const { value } = this.state
        try {
            const { result } = await searchApi.getSuggest({
                term: value
            })
            let suggests = []
            if (Object.prototype.toString.call(result) === '[object Object]') {
                const time = new Date().getTime()
                suggests = result.tag.map((item, index) => {
                    item.key = time + index
                    return item
                })
            } 

            this.setState({
                suggests
            })
        } catch (error) {
            this.setState({
                suggests: []
            })
        }
    }

    getURLSearch = props => {
        let str = null
        const { location: { search } } = props
        if (search) {
            const { keyword } = qs.parse(search.slice(1))
            str = keyword
        }
        return str
    }   

    componentDidMount() {
        this.props.toggleHeader(false)
        const keyword = this.getURLSearch(this.props)
        if (keyword) {            
            this.setStatus('result')
            this.props.setKeyword(keyword)
        } else {
            this.setStatus('init')
            this.getDefaultKey()
            this.getHotSearch()         
        }        
    }

    componentDidUpdate(prevProps) {        
        const prevKeyword = this.getURLSearch(prevProps)
        const keyword = this.getURLSearch(this.props)
        if (prevKeyword !== keyword) {
            this.setState({
                value: keyword
            }) 
            if (keyword) {            
                this.setStatus('result')
                this.props.setKeyword(keyword)
            } else {
                this.setStatus('init')
                this.getDefaultKey()
                this.getHotSearch()         
            }   
        }
    }

    componentWillUnmount() {
        this.props.toggleHeader(true)
    }

    render() {        
        const { historys, defaultKey, value, suggests, hots } = this.state
        return (
            <>
                <div className={css["sticky"]}>
                    <SearchBar
                        value={value}
                        placeholder={defaultKey ? defaultKey.show_name: '请输入搜索关键字'}
                        onSubmit={this.handleSearch}
                        onCancel={this.handleCancel}                        
                        onChange={this.handleChange}
                        onClear={this.handleClear}
                        showCancelButton
                    />
                </div>
                {
                    this.isInit && (
                        <>
                            <SearchHot list={hots} onSelect={this.triggerSearch} />
                            <SearchHistory list={historys} onSelect={this.triggerSearch} onClear={this.handleHistoryClear}/>
                        </>
                    )
                }
                {
                    this.isInput && <SearchSuggest list={suggests} onSelect={this.triggerSearch} />
                }
                { this.isResult && <SearchResult /> }
            </>
        )
    }
}

export default connect(
    state => ({ storeKeyword: state.searchKeyword }),
    {
        toggleHeader: createToggleHeaderAction,
        setKeyword: createSearchKeywordAction
    }
)(Search)